import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

public class UDPReceive {

    public static List<String> stationMacs = Arrays.asList("68B9D3D7BDD3", "68B9D3D7BE1B", "68B9D3D7C2A3", "68B9D3D7CECF", "68B9D3D7C6EB", "68B9D3D7D7C3", "68B9D3D7D0F3", "68B9D3D7CF13", "68B9D3D7D093", "68B9D3D7D98F");
    public static List<String> nodes = Arrays.asList("DB5BC1FEDBBD", "DE8C9AE72232", "D3525AEC28AE","");
    // public static String[] stationMacs = {"68B9D3D7BDD3", "68B9D3D7BE1B", "68B9D3D7C2A3", "68B9D3D7CECF", "68B9D3D7C6EB", "68B9D3D7D7C3", "68B9D3D7D0F3", "68B9D3D7CF13", "68B9D3D7D093", "68B9D3D7D98F"};
    // public static String[] nodes = {"DB5BC1FEDBBD", "DE8C9AE72232", "D3525AEC28AE"};


    public static void main(String[] args) {

        System.out.println("服务器 开始运行");

        // stationMacs.add("68B9D3D7BDD3");
        // stationMacs.add("68B9D3D7BE1B");
        // stationMacs.add("68B9D3D7C2A3");
        // stationMacs.add("68B9D3D7CECF");
        // stationMacs.add("68B9D3D7C6EB");
        // stationMacs.add("68B9D3D7D7C3");
        // stationMacs.add("68B9D3D7D0F3");
        // stationMacs.add("68B9D3D7CF13");
        // stationMacs.add("68B9D3D7D093");
        // stationMacs.add("68B9D3D7D98F");
        // nodes.add("DB5BC1FEDBBD");
        // nodes.add("DE8C9AE72232");
        // nodes.add("D3525AEC28AE");

        //开启接收数据的线程
        ReceiveThread receiveThread = new ReceiveThread();
        receiveThread.start();
    }


    /**
     * 服务器端监听客户端发送的信息
     */
    private static class ReceiveThread extends Thread {
        /**
         * 是否继续监听 , 循环控制变量
         */
        boolean isReceive = true;

        int count =0;
        /**
         * 存储发送数据的客户端信息
         */
        ArrayList<Client> clients = new ArrayList<>();

        @Override
        public void run() {
            super.run();

            System.out.println("开始接收");
//            long startTime = System.currentTimeMillis();
//            //创建Excel文件薄
//            XSSFWorkbook workbook=new XSSFWorkbook();
//            //创建工作表sheeet
//            Sheet sheet=workbook.createSheet();
//            //创建第一行
//            Row row=sheet.createRow(0);
//            String[] title={"sendIP","sendPort","stationMac","nodeMac","RSSI","timeStamp"};
//            Cell cell=null;
//            for (int i=0;i<title.length;i++) {
//                cell = row.createCell(i);
//                cell.setCellValue(title[i]);
//            }


            try {
                //I. 创建 DatagramSocket 对象 , 用于 UDP 数据包的发送和接收


                //1. UDP 数据包接收者 , 监听 8888 端口
                //      该 DatagramSocket 既可以接收数据包 , 也可以发送数据包
                InetAddress laddr = InetAddress.getLocalHost();
                DatagramSocket datagramSocket = new DatagramSocket(9000, laddr);
                System.out.println(laddr.toString());


                //II. 接收 UDP 数据包 , 无限循环接收来自客户端的信息 , 并根据不同的信息进行不同处理


                while (isReceive) {

                    //2. 接收数据包使用的缓冲区
                    byte[] receiveBuffer = new byte[1024];
                    //3. 接收 UDP 数据包使用的 DatagramPacket 对象
                    DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length);

                    //4. 接收 UDP 数据包
                    datagramSocket.receive(receivePacket);

                    //5. 获取发送端的 IP 地址
                    String sendIP = receivePacket.getAddress().getHostAddress();
                    //6. 获取发送端的端口号
                    int sendPort = receivePacket.getPort();
                    //7. 获取接收到的数据的长度
                    int receiveLen = receivePacket.getLength();
                    //8. 获取接收到的数据 , 并转为字符串
                    byte[] data = Arrays.copyOfRange(receivePacket.getData(), 0, receiveLen);
                    String receiveData = bytesToHexString(data);
                    System.out.println(receiveData);
                    //  String receiveData = new String(receivePacket.getData(), 0, receiveLen);
                    // 截取网关Mac和终端Mac:
                    String stationMac = receiveData.substring(22, 34);
                    String nodeMac = receiveData.substring(38, 50);
                    Integer rssi = Integer.parseInt(receiveData.substring(50, 52), 16) - 255;
//                    if (stationMacs.stream().anyMatch(stationMac::equalsIgnoreCase) && nodes.stream().anyMatch(nodeMac::equalsIgnoreCase)) {
                        count++;
                        long time = System.currentTimeMillis();
                        //9. 打印接收到的数据包信息
                        System.out.println("-------------------------------"+count);
                        System.out.println("服务器 接收到 " + sendIP + " : " + sendPort + " 发送的数据");
                        System.out.println("网关地址:" + stationMac + " 节点地址: " + nodeMac);
                        System.out.println("信号强度: " + rssi + " 时间戳: " + new Date(time));
                        System.out.println("-------------------------------");

//                        Row nextrow=sheet.createRow(count);
//                        Cell cell2=nextrow.createCell(0);
//                        cell2.setCellValue(sendIP);
//                        cell2=nextrow.createCell(1);
//                        cell2.setCellValue(sendPort);
//                        cell2=nextrow.createCell(2);
//                        cell2.setCellValue(stationMac);
//                        cell2=nextrow.createCell(3);
//                        cell2.setCellValue(nodeMac);
//                        cell2=nextrow.createCell(4);
//                        cell2.setCellValue(rssi);
//                        cell2=nextrow.createCell(5);
//                        cell2.setCellValue(time);

//                    }

//                    if(System.currentTimeMillis() - startTime >1000 * 60 *10){
//                        isReceive = false;
//                        try {
//                            //创建一个文件
//                            SimpleDateFormat formatter= new SimpleDateFormat("yyyy-MM-dd-HH-mm");
//                            String filePath = "C:/Server/ibeacon_hospital/data/rssi_test_"+formatter.format(new Date())+".xlsx";
//                            File file=new File(filePath);
//                            if (!file.exists()) {
//                                file.createNewFile();
//                            }
//                            file.createNewFile();
//                            FileOutputStream stream= new FileOutputStream(filePath);
//                            workbook.write(stream);
//                            stream.close();
//                            System.out.println("数据导出到："+filePath);
//                        } catch (IOException e) {
//                            e.printStackTrace();
//                        }
//                    }

                    //退出服务器循环
                    if ("exit".equals(receiveData)) {
                        isReceive = false;
                    }

                }


            } catch (SocketException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                System.out.println("服务器 运行结束");
            }
        }
    }

    /**
     * 封装向服务器端发送数据的客户端信息
     * 主要是保存客户端的 IP 地址和端口号
     */
    private static class Client {
        String ClientIP;
        String ClientPort;

        public Client(String clientIP, String clientPort) {
            ClientIP = clientIP;
            ClientPort = clientPort;
        }
    }

    /**
     * byte[]数组转换为16进制的字符串
     *
     * @param bytes 要转换的字节数组
     * @return 转换后的结果
     */
    public static String bytesToHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(0xFF & bytes[i]);
            if (hex.length() == 1) {
                sb.append('0');
            }
            sb.append(hex);
        }
        return sb.toString();
    }
}
